﻿using Aspose.Cells;
using Loogn.DataMeta;
using RazorEngine;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Generator
{
    public partial class Generator : Form
    {
        public Generator()
        {
            InitializeComponent();
        }

        private void Generator_Load(object sender, EventArgs e)
        {


            foreach (var item in Helper.ConnDict)
            {
                cbConnStr.Items.Add(item.Key);
            }
            bindTemplates();
        }
        void bindTemplates()
        {
            cbTemplate.Items.Clear();
            if (Directory.Exists("./Template"))
            {
                foreach (var file in new DirectoryInfo("./Template").GetFiles("*.cshtml"))
                {
                    cbTemplate.Items.Add(file.Name);
                }
            }
        }

        private void cbConnStr_SelectedIndexChanged(object sender, EventArgs e)
        {
            Meta meta = new Meta(Helper.ConnDict[cbConnStr.SelectedItem.ToString()]);
            var tables = meta.GetTables();
            dgv.DataSource = tables;

            foreach (DataGridViewRow row in dgv.Rows)
            {
                row.Cells[0].Value = true;
            }
            ckAll.Checked = true;

        }

        private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 0)
            {
                dgv.CurrentRow.Cells[0].Value = !true.Equals(dgv.CurrentRow.Cells[0].Value);
            }
        }

        private void labelTemplate_DoubleClick(object sender, EventArgs e)
        {
            bindTemplates();
        }

        private void btnGenerator_Click(object sender, EventArgs e)
        {
            List<string> tableNames = new List<string>();
            foreach (DataGridViewRow row in dgv.Rows)
            {
                if (true.Equals(row.Cells[0].Value))
                {
                    tableNames.Add(row.Cells[1].Value.ToString());
                }
            }
            if (tableNames.Count == 0)
            {
                return;
            }
            if (cbTemplate.SelectedItem == null)
            {
                return;
            }
            var template = cbTemplate.SelectedItem.ToString();
            string deskdir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            var dir = Path.Combine(deskdir, "generator_" + template);
            var modeDir = Directory.CreateDirectory(dir);
            this.Enabled = false;
            try
            {
                Meta meta = new Meta(Helper.ConnDict[cbConnStr.SelectedItem.ToString()]);
                var tables = meta.GetTablesWithColumns().Where(t => tableNames.Contains(t.Name));

                string modelTemplate = File.ReadAllText("Template/" + template, UTF8Encoding.UTF8);
                var cacheKey = Guid.NewGuid().ToString();
                foreach (var table in tables)
                {
                    var csfile = Razor.Parse<TableInfo>(modelTemplate, table, cacheKey);
                    File.WriteAllText(Path.Combine(modeDir.FullName, table.Name + ".cs"), csfile, UTF8Encoding.UTF8);
                }
                if (MessageBox.Show("生成成功,是否打开文件夹？", "生成成功", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK)
                {
                    System.Diagnostics.Process.Start("Explorer.exe", dir);
                }
                this.Enabled = true;
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.Message, "生成出错");
                this.Enabled = true;
            }
        }


        private void btnDBDesc_Click(object sender, EventArgs e)
        {
            List<string> tableNames = new List<string>();
            foreach (DataGridViewRow dgrow in dgv.Rows)
            {
                if (true.Equals(dgrow.Cells[0].Value))
                {
                    tableNames.Add(dgrow.Cells[1].Value.ToString());
                }
            }
            if (tableNames.Count == 0)
            {
                return;
            }

            this.Enabled = false;
            try
            {
                Meta meta = new Meta(Helper.ConnDict[cbConnStr.SelectedItem.ToString()]);
                var tables = meta.GetTablesWithColumns().Where(t => tableNames.Contains(t.Name));

                //var stream = NPOIStream(tables);
                var stream = AsposeCell(tables);

                SaveFileDialog saveFileDialog1 = new SaveFileDialog();
                saveFileDialog1.FileName = cbConnStr.SelectedItem.ToString() + "数据库文档.xls";
                //设置文件类型  
                saveFileDialog1.Filter = "excelx files(*.xlsx)|*.xlsx|excel files(*.xls)|*.xls|All files(*.*)|*.*";

                //设置默认文件类型显示顺序  
                saveFileDialog1.FilterIndex = 2;

                //保存对话框是否记忆上次打开的目录  
                saveFileDialog1.RestoreDirectory = true;

                //点了保存按钮进入  
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    using (var fs = saveFileDialog1.OpenFile())//输出文件  
                    {
                        stream.CopyTo(fs);
                    }
                }
            }
            finally
            {
                this.Enabled = true;
            }
        }

        private Stream AsposeCell(IEnumerable<TableInfo> tables)
        {
            Workbook wb = new Workbook(FileFormatType.Xlsx);
            wb.Worksheets.Clear();
            var ws = wb.Worksheets.Add("Sheet1");

            int rowIndex = 0;

            var headStyle = new Style
            {
                HorizontalAlignment = TextAlignmentType.Center,
            };
            headStyle.Font.Size = 20;
            headStyle.Font.Name = "微软雅黑";
            headStyle.Font.Color = Color.Red;

            var colStyle = new Style
            {
                HorizontalAlignment = TextAlignmentType.Center,
            };
            colStyle.Font.Size = 16;
            colStyle.Font.Name = "微软雅黑";
            colStyle.Font.Color = Color.Green;

            var cellStyle = new Style
            {
                HorizontalAlignment = TextAlignmentType.Center,
            };
            cellStyle.Font.Size = 14;
            cellStyle.Font.Name = "微软雅黑";

            var cellPKStyle = new Style
            {
                HorizontalAlignment = TextAlignmentType.Center,
            };
            cellPKStyle.Font.Size = 14;
            cellPKStyle.Font.Color = Color.Red;
            cellPKStyle.Font.Name = "微软雅黑";

            foreach (var table in tables)
            {

                //表头
                Range range = ws.Cells.CreateRange(rowIndex++, 0, 1, 7);
                var cell = range[0, 0];
                cell.PutValue(table.Name + "(" + table.Description + ")");
                cell.SetStyle(headStyle);
                range.Merge();

                int colIndex = 0;

                #region 列头

                cell = ws.Cells[rowIndex, colIndex++];
                cell.PutValue("字段名");
                cell.SetStyle(colStyle);

                cell = ws.Cells[rowIndex, colIndex++];
                cell.PutValue("是否自增");
                cell.SetStyle(colStyle);

                cell = ws.Cells[rowIndex, colIndex++];
                cell.PutValue("是否可空");
                cell.SetStyle(colStyle);

                cell = ws.Cells[rowIndex, colIndex++];
                cell.PutValue("数据类型");
                cell.SetStyle(colStyle);

                cell = ws.Cells[rowIndex, colIndex++];
                cell.PutValue("类型长度");
                cell.SetStyle(colStyle);

                cell = ws.Cells[rowIndex, colIndex++];
                cell.PutValue("默认值");
                cell.SetStyle(colStyle);


                cell = ws.Cells[rowIndex, colIndex++];
                cell.PutValue("描述");
                cell.SetStyle(colStyle);

                #endregion

                rowIndex++;
                foreach (var col in table.Columns)
                {
                    colIndex = 0;
                    cell = ws.Cells[rowIndex, colIndex++];

                    if (col.IsPrimaryKey)
                    {
                        cell.PutValue(col.Name + "(PK)");
                        cell.SetStyle(cellPKStyle);
                    }
                    else
                    {
                        cell.PutValue(col.Name);
                        cell.SetStyle(cellStyle);
                    }

                    cell = ws.Cells[rowIndex, colIndex++];
                    cell.PutValue(col.IsIdentity ? "√" : "");
                    cell.SetStyle(cellStyle);

                    cell = ws.Cells[rowIndex, colIndex++];
                    cell.PutValue(col.IsNullable ? "√" : "");
                    cell.SetStyle(cellStyle);

                    cell = ws.Cells[rowIndex, colIndex++];
                    cell.PutValue(col.SqlDataType);
                    cell.SetStyle(cellStyle);

                    cell = ws.Cells[rowIndex, colIndex++];
                    cell.PutValue(col.Length);
                    cell.SetStyle(cellStyle);

                    cell = ws.Cells[rowIndex, colIndex++];
                    cell.PutValue(col.IsIdentity ? "" : Helper.GetDefVal(col.DefaultValue));
                    cell.SetStyle(cellStyle);

                    cell = ws.Cells[rowIndex, colIndex++];
                    cell.PutValue(col.Description);
                    cell.SetStyle(cellStyle);

                    rowIndex++;
                }
                //空行
                rowIndex++;
            }
            ws.AutoFitColumns();
            ws.AutoFitRows();
            var ms = wb.SaveToStream();
            ms.Position = 0;
            return ms;
        }

        private void ckAll_CheckedChanged(object sender, EventArgs e)
        {
            foreach (DataGridViewRow row in dgv.Rows)
            {
                row.Cells[0].Value = ckAll.Checked;
            }
        }

        private void btnShowAPI_Click(object sender, EventArgs e)
        {
            API.Instance.Show();
            API.Instance.Activate();
        }
    }
}
